package order

import (
	"encoding/base64"
	"end/config"
	"end/entry"
	"end/httpEntry"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/skip2/go-qrcode"
	"net/http"
	"strconv"
	"time"
)

type Request struct {
	Orderid string `json:"orderid"`
}

func GenerateBase64QRCode(content string) (string, error) {
	// 生成二维码
	qrCode, err := qrcode.New(content, qrcode.Medium)
	if err != nil {
		return "", err
	}
	// 将二维码图像编码为PNG格式
	pngImage, err := qrCode.PNG(256)
	if err != nil {
		return "", err
	}
	// 将PNG格式的图像转换为Base64字符串
	base64Str := base64.StdEncoding.EncodeToString(pngImage)
	return base64Str, nil
}

// GetQrCode 获取二维码
func GetQrCode(r *gin.Engine) {
	r.GET("/order/get/qrcode/:id", httpEntry.LoginMiddleware(), func(context *gin.Context) {
		idStr := context.Param("id")
		id, err := strconv.Atoi(idStr)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		userinfo := context.MustGet("userinfo").(config.UserInfo)
		db := config.GetDb()
		var order entry.Order
		if err := db.Where("id = ?", id).First(&order).Error; err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10005,
				Error: httpEntry.ERROR10005,
			})
			return
		}
		// 不是用户的，或者已经核验过了
		if order.UserID != userinfo.Id || order.Status == config.STATUS2 {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		currentTime := time.Now().Unix()
		message := fmt.Sprintf("%d:%d", id, currentTime)
		encrypted, err := config.Encrypt(message)
		if err != nil {
			context.JSON(500, gin.H{"error": err.Error()})
			return
		}
		code, err := GenerateBase64QRCode(encrypted)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		context.JSON(200, gin.H{
			"code": 200, "qrcode": code,
		})
	})
}

// ConfirmOrder 确认订单
func ConfirmOrder(r *gin.Engine) {
	r.GET("/order/confirm/:key", httpEntry.LoginMiddleware(), func(c *gin.Context) {
		encryptedData := c.Param("key")
		power := 0
		allinfo := c.MustGet("allinfo").(config.AllInfo)
		var userinfo config.UserInfo
		for i := range allinfo.Additionals {
			userinfo.Identity = allinfo.Additionals[i].Type
			userinfo.Id = allinfo.Additionals[i].Id
		}
		if userinfo.Identity == "business" {
			power = 1
		} else if userinfo.Identity == "clerk" {
			power = 2
		} else {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10011,
				Error: httpEntry.ERROR10011,
			})
			return
		}
		decrypted, err := config.Decrypt(encryptedData)
		if err != nil {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10020,
				Error: httpEntry.ERROR10020,
			})
			return
		}

		// 解析解密后的数据，判断时间是否超过10分钟
		var id int
		var timestamp int64
		_, err = fmt.Sscanf(decrypted, "%d:%d", &id, &timestamp)
		if err != nil {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10020,
				Error: httpEntry.ERROR10020,
			})
			return
		}

		// 检查时间是否超过10分钟
		if time.Now().Unix()-timestamp > 600 {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10019,
				Error: httpEntry.ERROR10019,
			})
			return
		}

		// 根据订单id获取，
		db := config.GetDb()
		var order entry.Order
		if err := db.Where("id = ?", id).First(&order).Error; err != nil {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10005,
				Error: httpEntry.ERROR10005,
			})
			return
		}
		if order.Status != httpEntry.STATUS1 {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  100022,
				Error: httpEntry.ERROR10022,
			})
			return
		}

		// 判断这个商家是否有核销这个的能力
		// 如果是商家
		if power == 1 {
			if order.Businessid != userinfo.Id {
				c.JSON(http.StatusOK, httpEntry.BaseResponse{
					Code:  10011,
					Error: httpEntry.ERROR10011,
				})
				return
			}
		}

		// 如果是店员
		if power == 2 {
			var clerk entry.Clerk
			// 查询这个店员是否存在
			result := db.Where("id = ? and businessid = ?", userinfo.Id, order.Businessid).
				First(&clerk)
			if result.Error != nil {
				c.JSON(http.StatusOK, httpEntry.BaseResponse{
					Code:  10011,
					Error: httpEntry.ERROR10011,
				})
				return
			}
		}
		// 更新订单
		order.Status = httpEntry.STATUS2
		order.UpdateTime = time.Now()
		db.Updates(order)
		c.JSON(200, gin.H{"code": 200, "message": "核验成功！！！"})
	})
}

type BusinessRequest struct {
	Page   int `json:"page" binding:"required"`
	Status int `json:"status"`
}

type BusinessAllCommodityRequest struct {
	Page       int `json:"page" binding:"required"`
	Businessid int `json:"businessid" binding:"required"`
}

// BusinessAllCommodity 商家id获取订单获取商品
func BusinessAllCommodity(r *gin.Engine) {
	r.POST("/order/business/all", httpEntry.LoginMiddleware(), func(context *gin.Context) {
		var businessCommodityRequest BusinessAllCommodityRequest
		err := context.ShouldBind(&businessCommodityRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		db := config.GetDb()
		var commodities []entry.Commodity
		// 获取数据，要求商品是上架状态
		db.Where("businessid = ? and status & ?", businessCommodityRequest.Businessid, httpEntry.STATUS2).
			Offset((businessCommodityRequest.Page - 1) * 30).Limit(30).
			Order("createtime desc").Find(&commodities)
		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取成功",
			"data":    commodities,
		})
	})
}

type GetAllOrderRequest struct {
	Status int `json:"status" binding:"required"`
	Page   int `json:"page" binding:"required"`
}

type Dto struct {
	entry.Order
	Commodity entry.Commodity `json:"commodity" gorm:"foreignkey:commodityid"`
	User      User            `json:"user" gorm:"foreignkey:userid"`
}

type User struct {
	ID                int       `json:"id" gorm:"column:id"`
	Nick              string    `json:"nick" gorm:"column:nick"`
	Img               string    `json:"img" gorm:"column:img"`
	Age               int       `json:"age" gorm:"column:age"`
	Phone             string    `json:"phone" gorm:"column:phone"`
	PoliticalOutlook  string    `json:"political_outlook" gorm:"column:political_outlook"`
	Address           string    `json:"address" gorm:"column:address"`
	PersonalSignature string    `json:"personal_signature" gorm:"column:personal_signature"`
	CreateTime        time.Time `json:"createtime" gorm:"column:createtime"`
	UpdateTime        time.Time `json:"updatetime" gorm:"column:updatetime"`
}

func (Dto) TableName() string {
	return "order"
}

func GetAllOrder(r *gin.Engine) {
	r.POST("/order/all/business", httpEntry.LoginMiddleware(), httpEntry.BusinessMiddleware(), func(context *gin.Context) {
		var getAllOrderRequest GetAllOrderRequest
		err := context.ShouldBind(&getAllOrderRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		userinfo := context.MustGet("userinfo").(config.UserInfo)
		db := config.GetDb()
		var orders []Dto
		db.Preload("Commodity").
			Preload("User").
			Where("status & ? and businessid = ?", getAllOrderRequest.Status, userinfo.Id).
			Offset((getAllOrderRequest.Page - 1) * 20).
			Limit(20).Order("createtime desc").Find(&orders)
		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "成功",
			"data":    orders,
		})
	})
}
